package org.ttjhome.html.servlet;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.JSONException;
import org.json.JSONObject;
import org.ttjhome.util.StringUtils;








public class FileUploadServlet extends HttpServlet {
	public static final String UPLOADPATH="/upload/";
	private static final long serialVersionUID = 1L;
	private static final String CONTENT_TYPE_UNACCEPTABLE = "{ERROR: 'Content type unacceptable. "
		+ " Only xls file can be uploaded'}";
	private static final long MAX_SIZE = 1000 * 50000;
	private static final String SIZE_UNACCEPTABLE =  "{ERROR: 'File size must be " + MAX_SIZE + " bytes or less'}";
	private static final String SUCCESS_MESSAGE =  "{OK: 'File upload succeeded'}";
	
	
	private static final Logger log = Logger.getLogger(FileUploadServlet.class.getName());
	private String uploadPath;
	private String  contextPath="";

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
	{
		
		uploadPath=this.getServletContext().getRealPath(UPLOADPATH);
		contextPath = this.getServletContext().getRealPath("");
		contextPath = "/"+StringUtils.parseFileName(contextPath);
		
	
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("utf-8"); 
		List items = null;
		JSONObject json = new JSONObject();

		try 
		{
			json.put("success", true);
			json.put("error", "uploaded successfully");
			json.put("code", "232");
			items = upload.parseRequest(request);
		}
		catch (Exception e) 
		{
			log.warning("Upload error" + e.getMessage());
		}
		
		Iterator it = items.iterator();
		List<String> filenames= new ArrayList<String>();
		String workaround ="";
		while (it.hasNext()) 
		{
			FileItem item = (FileItem) it.next();
			if(!item.isFormField()) {
				try
				{
					String filename=processFile(item);
					filenames.add(filename);
					workaround= filename;
				}
				catch(Exception ex)
				{
					log.log(Level.WARNING, "Upload file process error" , ex);
					System.out.println("Upload file process error"+ex);
					try {
						json.put("success", false);
						json.put("error", ex.getMessage());
					} catch (JSONException e) {
						log.warning("error"+e);
					}
				}
			}
		}
		//even if there is file fail, we still can return back the successful file names
//		try {
//			json.put("filenames", filenames);
//		} catch (JSONException e) {
//			log.warning("error"+e);
//		}
//		
		response.setContentType("application/text");
		response.setCharacterEncoding("utf-8");
		response.getWriter().write(workaround);
		response.getWriter().close();

	}


	private synchronized String processFile(FileItem item) throws Exception
	{
		if (!isSizeAcceptable(item)){
			throw new RuntimeException(SIZE_UNACCEPTABLE) ;
		}
		
		log.info("upload file: " + item.getName());
		String clientFilename = StringUtils.parseFileName(item.getName());
		
		//escape white space 
		clientFilename = StringUtils.removeWhiteSpace(clientFilename);
		
		log.info("after trans upload file: " + item.getName());
		String filepath = uploadPath+"\\"+item.getFieldName();
		File file = new File(filepath);
		if(!file.exists())file.mkdirs();
		file = new File(filepath + File.separator + clientFilename);
		item.write(file);
		return contextPath+UPLOADPATH+item.getFieldName()+"/"+clientFilename;

	}
	
	private boolean isSizeAcceptable(FileItem item) 
	{
		return item.getSize() <= MAX_SIZE;
	}
	
	private boolean isContentTypeAcceptable(FileItem item) 
	{
		String fileName = item.getName();
		//if(!fileName.toLowerCase().endsWith("wav"))return false;
		return true;
	}
	

}
